<?php

class GoodsService extends AbstractService
{
    /**
     * @var GoodsService
     */
    private static $instance;

    /**
     * Get the instance of GoodsService.
     *
     * @return GoodsService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new GoodsService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理创建时的逻辑
     *
     * @param int $shardId
     * @return void
     */
    public function handleCreate($shardId)
    {

    }

    /**
     * 处理登录时的逻辑
     * 1. 离线销售
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {
        //        2018.03.09 策划需求，移除收银机，并且每次收获金币，是再整个货架销售的所有道具全部销售完成后获取
          //    GoodsService::get()->offlineSell($userId);
    }

    /**
     * 提供当前 service 数据
     *
     * @param int $userId
     * @param boolean $visitMode default false
     * @return array(GoodsVoList)
     */
    public function info($userId, $visitMode = false)
    {
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        return array(
            $goodsList
        );
    }

    /**
     * @param $userId
     * @param $gridId
     * @param $girdLayer
     * @return array
     * @throws SzException
     */
    public function upgradeFlowerStand($userId, $gridId, $girdLayer) {
        list($decorId) = BuildingService::get()->getGroundAndDecorRecord($userId, $gridId, $girdLayer);
        /**
         * @var GoodsVoList $goodsList
         * @var GoodsVo $goods
         */
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        $goods = $goodsList->getElement($decorId, false);
        if (is_null($goods)) {
            $goods = new GoodsVo($userId,    // userId
                $decorId,   // decorId
                null,       // itemDefId
                0,          // count
                0,          // flower
                -1,         // wrapperId
                json_encode([]),    // gifts
                null,       // harvestTime
                0,          // isSell
                json_encode([]),    // rewards
                1,
                true);
        }
        $level = $goods->getLevel() + 1;
        $goodsSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_UPGRADE, $level, true);
        $output = '';
        foreach ($goodsSetting['needItems'] as $entityId=>$count) {
            GameService::get()->handleEntity($userId, $entityId, $count, true);
            $output .= $entityId.':'.$count.'|';
        }
        CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_FLOWER_SHOP_SELL,$userId,0,$output,'upgradeFlowerStand');//消耗资源上报

        $goods->setLevel($level);
        if ($goods->isInsert() && !SzUtility::checkArrayKey($decorId, $goodsList->getList())) {
            $goodsList->addElement($goods);
            $goodsList->setElement($decorId, $goods);
        } else {
            $goodsList->updateElement($decorId, $goods);
        }

        SzPersister::get()->setVoList($goodsList);
        return $goods->toArray();
    }

    /**
     * 商品上架.
     *
     * @param int $userId
     * @param string $gridId
     * @param int $girdLayer
     * @param int $itemDefId
     * @param int $count
     * @param int $wrapperId
     * @param array $giftIds
     * @param int $reqTime
     * @throws SzException 20401
     * @return GoodsVo
     */
    public function onShelf($userId, $gridId, $girdLayer, $itemDefId, $count, $wrapperId, $giftIds, $reqTime)
    {
        list($decorId) = BuildingService::get()->getGroundAndDecorRecord($userId, $gridId, $girdLayer);
        $goodsSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_SELL, $itemDefId, true);

        /**
         * @var GoodsVoList $goodsList
         * @var GoodsVo $goods
         */
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        $goods = $goodsList->getElement($decorId, false);

        if (is_null($goods)) {
            $goods = new GoodsVo($userId,    // userId
                $decorId,   // decorId
                null,       // itemDefId
                0,          // count
                0,          // flower
                -1,         // wrapperId
                json_encode([]),    // gifts
                null,       // harvestTime
                0,          // isSell
                json_encode([]),    // rewards
                1,
                true);
        }

        if ($goods->getCount() > 0) {
            throw new SzException(20401, array($decorId, $goods->getCount()));
        }

        $level = $goods->getLevel();
        if ($level > 1) {
            $flowerUpgradeSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_UPGRADE, $level, true);
            if ($count > $flowerUpgradeSetting['maxNum']) {
                $count = $flowerUpgradeSetting['maxNum'];
            }
        }

        // 计算上架数量
        $goodsCount = abs($goodsSetting['itemIncreaseRate'] * $count);

        // 扣除上架道具
        list($itemList) = ItemService::get()->processItems($userId, [$itemDefId => -$count]);
        SzPersister::get()->setVoList($itemList);

        // 更新花架
        $goods->setItemDefId($itemDefId);
        $goods->setCount($goodsCount);
        $goods->setFlower($count);
        $goods->setHarvestTime($reqTime + ($goodsSetting['sellTime'] * $goodsCount));
        $goods->setIsSell(0);
        $goods->setWrapperId($wrapperId);
        $goods->setGifts($giftIds);
        $goods->setRewards([]);

        if ($goods->isInsert() && !SzUtility::checkArrayKey($decorId, $goodsList->getList())) {
            $goodsList->addElement($goods);
            $goodsList->setElement($decorId, $goods);
        } else {
            $goodsList->updateElement($decorId, $goods);
        }

        SzPersister::get()->setVoList($goodsList);

        // 更新任务进度
        MissionService::get()->progress($userId, GameConst::ENTITY_ACTION_SELL_ON_SELL, GameConst::ENTITY_TYPE_ITEM, $itemDefId, $count);
        TreeService::get()->updateProgress($userId,GameConst::TREE_TASK_SELL_IKEBANA,$count);
        NewTaskService::get()->updateDailyTask($userId,GameConst::DAILY_TASK_SELL_IKEBANA,$count);
        TrainingService::get()->updateProgress($userId,GameConst::TRAINING_TASK_SELL_IKEBANA,$count);

        $activityPersonalGoalsId = ActivityService::get()->getActivityPersonalGoalsIndexId($userId,$reqTime);
        if ($activityPersonalGoalsId) {
            ActivityService::get()->updateActivityPersonalGoalsNum($userId,$activityPersonalGoalsId,abs($count),false);
        }

        // 更新活动任务进度
        $activityData = ActivityService::get()->getActivityIdAndPosition($userId,GameConst::ACTIVITY_TASK_1);
        if (!empty($activityData)){
            ActivityTaskService::get()->updateActivityTaskProgress($userId,$activityData['aid'],$activityData['position'],$count);
        }


        // 更新合约任务进度
        $contractData = ContractService::get()->getContractOpenAndTask($userId,GameConst::CONTRACT_TASK_4,$reqTime);
        if (!empty($contractData) && !empty($contractData['task']) && !empty($contractData['session'])){
            if ($reqTime >= $contractData['start'] && $reqTime <= $contractData['end']){
                ContractService::get()->updateTaskProgress($userId,$contractData['session'],$contractData['task']['pos'],$contractData['task']['taskId'],$reqTime,$count);
            }
        }

        //跟新店铺经营数据
        UserShopService::get()->record($userId,1,2002,$count,$reqTime);

        //社团竞赛任务进度添加
        UnionCompetitionService::get()->addCompetitionTaskProcess($userId,GameConst::UNION_COMPETITION_TASK_12, $reqTime,$count);

        return $goods;
    }

    /**
     * 商品开始出售
     *
     * @param $userId int 玩家ID
     * @param $gridId string 地块Id
     * @param $girdLayer int 层级Id
     * @param $reqTime int
     * @throws SzException
     * @return GoodsVo
     */
    public function onSell($userId, $gridId, $girdLayer, $reqTime)
    {
        list($decorId) = BuildingService::get()->getGroundAndDecorRecord($userId, $gridId, $girdLayer);

        /**
         * @var GoodsVoList $goodsList
         * @var GoodsVo $goods
         */
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        $goods = $goodsList->getElement($decorId);

        $goodsSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_SELL, $goods->getItemDefId(), true);

        // 判断是否已经出售
        if ($goods->getIsSell() >= 1) {
            throw new SzException(20405, $decorId);
        }

        // 更新货架数据
        $goods->setIsSell(1);
        $goods->setHarvestTime($reqTime + ($goodsSetting['sellTime'] * $goods->getCount()));
        $goodsList->updateElement($decorId, $goods);

        SzPersister::get()->setVoList($goodsList);

        // 更新任务进度--在花台上出售花品X次
        MissionService::get()->progress($userId, GameConst::ENTITY_ACTION_GOODS_SELL, GameConst::ENTITY_TYPE_ITEM, $goods->getItemDefId(), 1);

        return $goods;
    }

    /**
     * 货架商品出售
     *
     * @param int $userId
     * @param GoodsVo $goods
     * @param int $sellCount default 1
     * @param int $cashierValue default 0
     * @param boolean $throwErr default true
     * @throws SzException
     * @return int $cashierValue
     */
    private function sellGoods($userId, $goods, $sellCount = 1, $cashierValue = 0, $throwErr = true)
    {
        $decorId = $goods->getDecorId();
        $itemDefId = $goods->getItemDefId();

        $flowerSellSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_SELL, $itemDefId, true);

        if ($goods->getIsSell() == 0) {
            if ($throwErr) {
                throw new SzException(20406, $decorId);
            } else {
                return $cashierValue;
            }
        }

        if ($goods->getCount() == 0) {
            if ($throwErr) {
                throw new SzException(20402, array($decorId, $goods->getCount()));
            } else {
                return $cashierValue;
            }
        }

        // 计算商品单价
        $sellPrice = $flowerSellSetting['price'];
        // 收银机增加商品总价：收银机当前金币数量 + 单价 * 数量
        $cashierValue += $sellPrice * $sellCount;

        // 更新商品数量
        $goods->setCount($goods->getCount() - $sellCount);
        // 更新任务进度
        MissionService::get()->progress($userId, GameConst::ENTITY_ACTION_SELL_SELL, GameConst::ENTITY_TYPE_ITEM, $itemDefId, $sellCount);

        return $cashierValue;
    }

    /**
     * 销售加速(全部卖出)
     *
     * @param int $userId
     * @param int $gridId
     * @param int $girdLayer
     * @param int $cliCost
     * @param int $reqTime
     * @throws SzException
     * @return array
     */
    public function payForSpeedUp($userId, $gridId, $girdLayer, $cliCost, $reqTime)
    {
        list($decorId) = BuildingService::get()->getGroundAndDecorRecord($userId, $gridId, $girdLayer);

        /**
         * @var GoodsVoList $goodsList
         * @var GoodsVo $goods
         */
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        $goods = $goodsList->getElement($decorId);
        $itemDefId = $goods->getItemDefId();
        $sellCount = $goods->getCount();

        if ($goods->getIsSell() == 0) {
            throw new SzException(20406, $decorId);
        }

        if ($sellCount == 0) {
            throw new SzException(20402, array($decorId, $sellCount));
        }

        $flowerSellSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_SELL, $itemDefId, true);

        // 扣除加速花费
        GameService::get()->handleSpeedUp($userId, $flowerSellSetting['coolDownId'], $goods->getHarvestTime(), $reqTime, 'indoor_speed_sell_' . $itemDefId, $cliCost);

        // 更新商品信息
        $goods->setHarvestTime($reqTime);
        $goodsList->updateElement($decorId, $goods);
        SzPersister::get()->setVoList($goodsList);

        // 数据采集：加速卖花
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:indoor|action:speed_sell|',
                'item' => $itemDefId,
                'value' => $sellCount
            )
        ));

        return array($goodsList);
    }

    /**
     * 获取售空奖励
     * @param $userId
     * @param $gridId
     * @param $girdLayer
     * @param $reqTime
     * @return bool
     * @throws SzException
     */
    public function selloutReward($userId, $gridId, $girdLayer,$reqTime)
    {
        if ($reqTime <= 0){
            $reqTime = GameService::get()->getReqTime();
        }
        list($decorId) = BuildingService::get()->getGroundAndDecorRecord($userId, $gridId, $girdLayer);

        /**
         * @var $goodsList GoodsVoList
         * @var $goods GoodsVo
         */
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        $goods = $goodsList->getElement($decorId);
        $item = $goods->getItemDefId();

        // 判断是否销售完，只有销售完才能领取奖励
        $goodNum = $goods->getCount();
        if ($goods->getCount() == 0) {
            throw new SzException(20411, $goods->getItemDefId());
        }

        if ($goods->getHarvestTime() > $reqTime + GameConst::MULTI_REQ_TIME_DELTA) {
            throw new SzException(20403, array($decorId, $goods->getHarvestTime(), $reqTime));
        }

        //获取插花作品的所需花朵
        $flowers = array();
        $goodConfigs= SzConfig::get()->loadAppConfig(GameConst::CONFIG_IKEBANA_ARRANGEMENT_TWO, null, true);
        foreach ($goodConfigs as $key=>$data){
            if ($data['vaseCombination'][1] == $item){
                $flowers = $data['flowerCombinationId'];
                break;
            }
        }
        if (empty($flowers)){
            return false;
        }

        $reward = array();
        foreach ($flowers as $flower=>$flowerNum){
            if (!isset($reward[$flower][GameConst::ENTITY_ACTION_GET_TOKEN])) {
                $reward[$flower][GameConst::ENTITY_ACTION_GET_TOKEN] = 0;
            }

            //20200409
            //获取玩家该花朵是否具有金币数量加成
            $flowerReward = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ORDER_REWARD, $flower, true);
            $goldNum = $flowerReward['gold']*$goodNum;
            $cashBuff = FlowersUpgradeService::get()->getFlowerBuff($userId,$flower,GameConst::FLOWER_TYPE_1);
            if (!empty($cashBuff)){
                if ($cashBuff[0] == 2){
                    $goldNum = ($flowerReward['gold'] + $cashBuff[1])*$goodNum;
                }
                if ($cashBuff[0] == 1){
                    $goldNum = ceil($flowerReward['gold']*(1+$cashBuff[1]/100))*$goodNum;
                }
            }
            $reward[$flower][GameConst::ENTITY_ACTION_GET_TOKEN] += intval($goldNum);
//            $reward[$flower][GameConst::ENTITY_ACTION_GET_EXP] = $reward[$flower][GameConst::ENTITY_ACTION_GET_TOKEN] + $flowerReward['experience']*$goodNum;
        }

        $cashierValue = 0;
        foreach ($reward as $fid=>$tempNum){
            $cashierValue += $tempNum[GameConst::ENTITY_ACTION_GET_TOKEN];
        }

        $itemDefId = $goods->getItemDefId();
        $flowerSellSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_ITEM_FLOWER_SELL, $itemDefId, true);
        $cashierValue = floor($cashierValue*($flowerSellSetting['additionRatio']/100));
        // 获得金币
//        $cashierValue = $this->sellGoods($userId, $goods, $goods->getCount(), 0, false);
        $halfCashierValue = ceil($cashierValue/2);

        //获取玩家周年庆buff
        /**
         * @var ModuleProfileInfoVoList $profileInfoList
         * @var ModuleProfileInfoVo $profileInfoTable
         */
        $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);
        $profileInfoTable = $profileInfoList->getElement(GameConst::USER_ANNIVERSARY_SHOP_TABLE,false);

        $orderBuffStatus = VideoService::get()->getBuffStatus($userId,GameConst::VIDEO_BUFF_FLOWER,$reqTime);
        if ($orderBuffStatus) {
            $videoSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_VIDEO, GameConst::VIDEO_BUFF_FLOWER, true);
            if ($videoSetting) {
                $cashierValue = $videoSetting['sp_reward'][0] * $cashierValue;
            }
        }

        if ($profileInfoTable){
            if ($profileInfoTable->getInfo() > $reqTime){
                $cashierValue = $cashierValue + $halfCashierValue;
            }
        }

        GameService::get()->handleEntity($userId, GameConst::ENTITY_ACTION_GET_TOKEN, $cashierValue, true);
        $tid = GameConst::ENTITY_ACTION_GET_TOKEN . ':' . $cashierValue . '|';

        CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_FLOWER_SHOP_SELL,$userId,1,$tid,'selloutReward');//获得资源上报

        // 判断奖励是否已经领取
        //        $rewards = $goods->getRawRewards();
        //        foreach ($rewards as $entityId => $count) {
        //            GameService::get()->handleEntity($userId, $entityId, $count, true);
        //            if ($count) {
        //                $tid .= $entityId . ':' . $count . '|';
        //            }
        //        }

        // 更新奖励
        $goods->setCount(0);
        $goods->setRewards([]);
        $goodsList->updateElement($decorId, $goods);
        SzPersister::get()->setVoList($goodsList);
        // 更新任务进度
        MissionService::get()->progress($userId, GameConst::ENTITY_ACTION_SELL_SELL, GameConst::ENTITY_TYPE_ITEM, $item, $goods->getCount());


        // 数据采集：卖花收获
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:flowershop|action:collect|',
                'item' => $goods->getItemDefId(),
                'value' => 1
            )
        ));

        // 数据采集：卖花收获产出
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
            'clientData' => array(
                'tid' => $tid,
                'item' => 'flowershop_sell&' . $goods->getItemDefId(),
            )
        ));

        return true;
    }

    /**
     * 下架未开售的花
     * @param $userId
     * @param $gridId
     * @param $girdLayer
     * @param $reqTime
     * @throws SzException
     * @return bool
     */
    public function offShelf($userId, $gridId, $girdLayer, $reqTime)
    {
        list($decorId) = BuildingService::get()->getGroundAndDecorRecord($userId, $gridId, $girdLayer);
        /**
         * @var GoodsVoList $goodsList
         * @var GoodsVo $goods
         */
        $goodsList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_GOODS);
        $goods = $goodsList->getElement($decorId);
        if ($goods->getIsSell()) {
            throw new SzException(20405, $decorId);
        }
        if ($goods->getCount() == 0) {
            throw new SzException(20402, [$decorId, 0]);
        }
        $itemSetting = SzConfig::get()->loadAppConfig(ModuleItemConst::CONFIG_ITEM_DEFS, $goods->getItemDefId(), true);

        $entityId = EntityService::get()->buildEntityId("72", $itemSetting['moduleId'], $goods->getItemDefId());
        $outputTid = $entityId . ':' . $goods->getCount() . '|';
        GameService::get()->handleEntity($userId, $entityId, $goods->getCount(), true);
        CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_FLOWER_SHOP_SELL,$userId,1,$outputTid,'offShelf');//获得资源上报

        $goods->setCount(0);
        $goods->setRewards([]);
        $goods->setHarvestTime($reqTime);
        $goodsList->updateElement($decorId, $goods);
        SzPersister::get()->setVoList($goodsList);

        // 数据采集：室内卖花展示撤销
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:indoor|action:cancel|',
                'item' => $goods->getItemDefId(),
                'value' => 1
            )
        ));

        // 数据采集：室内卖花撤销产出物品
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
            'clientData' => array(
                'tid' => $outputTid,
                'item' => 'indoor_cancel',
            )
        ));
        return true;
    }
}
